--- /dev/null
+/*
+ * Copyright © 2014 Canonical Limited
+ * Copyright © 2013 Carlos Garnacho
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gtkmenusectionbox.h"
+
+#include "gtkwidgetprivate.h"
+#include "gtklabel.h"
+#include "gtkmenutracker.h"
+#include "gtkmodelbutton.h"
+#include "gtkseparator.h"
+#include "gtksizegroup.h"
+#include "gtkstack.h"
+#include "gtkstylecontext.h"
+#include "gtkpopover.h"
+#include "gtkorientable.h"
+
+typedef GtkBoxClass GtkMenuSectionBoxClass;
+
+struct _GtkMenuSectionBox
+{
+ GtkBox parent_instance;
+
+ GtkSizeGroup *size_group;
+ GtkMenuSectionBox *toplevel;
+ GtkMenuTracker *tracker;
+ GtkBox *item_box;
+ GtkWidget *separator;
+ guint separator_sync_idle;
+};
+
+G_DEFINE_TYPE (GtkMenuSectionBox, gtk_menu_section_box, GTK_TYPE_BOX)
+
+void gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
+ gint *n_items);
+void gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
+ GtkMenuSectionBox *toplevel,
+ GtkWidget *focus);
+GtkWidget * gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
+ GtkMenuSectionBox *toplevel);
+
+static void
+gtk_menu_section_box_sync_item (GtkWidget *widget,
+ gpointer user_data)
+{
+ gint *n_items = user_data;
+
+ if (GTK_IS_MENU_SECTION_BOX (widget))
+ gtk_menu_section_box_sync_separators (GTK_MENU_SECTION_BOX (widget), n_items);
+ else
+ (*n_items)++;
+}
+
+void
+gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
+ gint *n_items)
+{
+ gboolean should_have_separator;
+ gint n_items_before = *n_items;
+
+ gtk_container_foreach (GTK_CONTAINER (box->item_box), gtk_menu_section_box_sync_item, n_items);
+
+ should_have_separator = n_items_before > 0 && *n_items > n_items_before;
+
+ if (box->separator == NULL)
+ return;
+
+ if (should_have_separator == (gtk_widget_get_parent (box->separator) != NULL))
+ return;
+
+ if (should_have_separator)
+ gtk_box_pack_start (GTK_BOX (box), box->separator, FALSE, FALSE, 0);
+ else
+ gtk_container_remove (GTK_CONTAINER (box), box->separator);
+}
+
+static gboolean
+gtk_menu_section_box_handle_sync_separators (gpointer user_data)
+{
+ GtkMenuSectionBox *box = user_data;
+ gint n_items = 0;
+
+ gtk_menu_section_box_sync_separators (box, &n_items);
+
+ box->separator_sync_idle = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+gtk_menu_section_box_schedule_separator_sync (GtkMenuSectionBox *box)
+{
+ box = box->toplevel;
+
+ if (!box->separator_sync_idle)
+ box->separator_sync_idle = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE, /* before resize... */
+ gtk_menu_section_box_handle_sync_separators,
+ box, NULL);
+}
+
+static void
+gtk_popover_item_activate (GtkWidget *button,
+ gpointer user_data)
+{
+ GtkMenuTrackerItem *item = user_data;
+
+ gtk_menu_tracker_item_activated (item);
+
+ if (gtk_menu_tracker_item_get_role (item) == GTK_MENU_TRACKER_ITEM_ROLE_NORMAL)
+ gtk_widget_hide (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER));
+}
+
+static void
+gtk_menu_section_box_remove_func (gint position,
+ gpointer user_data)
+{
+ GtkMenuSectionBox *box = user_data;
+ GList *children;
+
+ children = gtk_container_get_children (GTK_CONTAINER (box->item_box));
+ gtk_widget_destroy (g_list_nth_data (children, position));
+ g_list_free (children);
+
+ gtk_menu_section_box_schedule_separator_sync (box);
+}
+
+static gboolean
+get_ancestors (GtkWidget *widget,
+ GType widget_type,
+ GtkWidget **ancestor,
+ GtkWidget **below)
+{
+ GtkWidget *a, *b;
+
+ a = NULL;
+ b = widget;
+ while (b != NULL)
+ {
+ a = gtk_widget_get_parent (b);
+ if (!a)
+ return FALSE;
+ if (g_type_is_a (G_OBJECT_TYPE (a), widget_type))
+ break;
+ b = a;
+ }
+
+ *below = b;
+ *ancestor = a;
+
+ return TRUE;
+}
+
+static void
+close_submenu (GtkWidget *button,
+ gpointer data)
+{
+ GtkMenuTrackerItem *item = data;
+ GtkWidget *stack;
+ GtkWidget *parent;
+ GtkWidget *focus;
+
+ if (gtk_menu_tracker_item_get_should_request_show (item))
+ gtk_menu_tracker_item_request_submenu_shown (item, FALSE);
+
+ focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
+ get_ancestors (focus, GTK_TYPE_STACK, &stack, &parent);
+ gtk_stack_set_visible_child (GTK_STACK (stack), parent);
+ gtk_widget_grab_focus (focus);
+}
+
+static void
+open_submenu (GtkWidget *button,
+ gpointer data)
+{
+ GtkMenuTrackerItem *item = data;
+ GtkWidget *stack;
+ GtkWidget *child;
+ GtkWidget *focus;
+
+ if (gtk_menu_tracker_item_get_should_request_show (item))
+ gtk_menu_tracker_item_request_submenu_shown (item, TRUE);
+
+ focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
+ get_ancestors (focus, GTK_TYPE_STACK, &stack, &child);
+ gtk_stack_set_visible_child (GTK_STACK (stack), child);
+ gtk_widget_grab_focus (focus);
+}
+
+static void
+gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
+ gint position,
+ gpointer user_data)
+{
+ GtkMenuSectionBox *box = user_data;
+ GtkWidget *widget;
+
+ if (gtk_menu_tracker_item_get_is_separator (item))
+ {
+ widget = gtk_menu_section_box_new_section (item, box->toplevel);
+ }
+ else if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU))
+ {
+ widget = g_object_new (GTK_TYPE_MODEL_BUTTON, "has-submenu", TRUE, NULL);
+ g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
+ gtk_menu_section_box_new_submenu (item, box->toplevel, widget);
+ gtk_widget_show (widget);
+ }
+ else
+ {
+ widget = gtk_model_button_new ();
+
+ g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "role", widget, "action-role", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "toggled", widget, "toggled", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "accel", widget, "accel", G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (widget, "clicked", G_CALLBACK (gtk_popover_item_activate), item);
+ }
+
+ gtk_widget_show (widget);
+
+ g_object_set_data_full (G_OBJECT (widget), "GtkMenuTrackerItem", g_object_ref (item), g_object_unref);
+
+ gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
+ gtk_container_add (GTK_CONTAINER (box->item_box), widget);
+ gtk_box_reorder_child (GTK_BOX (box->item_box), widget, position);
+
+ gtk_menu_section_box_schedule_separator_sync (box);
+}
+
+static void
+gtk_menu_section_box_init (GtkMenuSectionBox *box)
+{
+ GtkWidget *item_box;
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (box), GTK_ORIENTATION_VERTICAL);
+
+ box->toplevel = box;
+
+ item_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ box->item_box = GTK_BOX (item_box);
+ gtk_box_pack_end (GTK_BOX (box), item_box, FALSE, FALSE, 0);
+ gtk_widget_show (item_box);
+
+ gtk_widget_set_halign (GTK_WIDGET (box), GTK_ALIGN_FILL);
+ g_object_set (box, "margin", 10, NULL);
+
+}
+
+static void
+gtk_menu_section_box_dispose (GObject *object)
+{
+ GtkMenuSectionBox *box = GTK_MENU_SECTION_BOX (object);
+
+ g_print ("disposed %p\n", object);
+
+ if (box->separator_sync_idle)
+ {
+ g_source_remove (box->separator_sync_idle);
+ box->separator_sync_idle = 0;
+ }
+
+ G_OBJECT_CLASS (gtk_menu_section_box_parent_class)->dispose (object);
+}
+
+static void
+gtk_menu_section_box_class_init (GtkMenuSectionBoxClass *class)
+{
+ G_OBJECT_CLASS (class)->dispose = gtk_menu_section_box_dispose;
+}
+
+void
+gtk_menu_section_box_new_toplevel (GtkStack *stack,
+ GMenuModel *model,
+ const gchar *action_namespace)
+{
+ GtkMenuSectionBox *box;
+
+ box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL);
+ box->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_add_widget (box->size_group, GTK_WIDGET (box));
+ gtk_stack_add_named (stack, GTK_WIDGET (box), "main");
+
+ box->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (_gtk_widget_get_action_muxer (GTK_WIDGET (box))),
+ model, TRUE, FALSE, action_namespace,
+ gtk_menu_section_box_insert_func,
+ gtk_menu_section_box_remove_func, box);
+
+ gtk_widget_show (GTK_WIDGET (box));
+}
+
+void
+gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
+ GtkMenuSectionBox *toplevel,
+ GtkWidget *focus)
+{
+ GtkMenuSectionBox *box;
+ GtkWidget *button;
+
+ box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL);
+ box->size_group = g_object_ref (toplevel->size_group);
+ gtk_size_group_add_widget (box->size_group, GTK_WIDGET (box));
+
+ button = g_object_new (GTK_TYPE_MODEL_BUTTON,
+ "has-submenu", TRUE,
+ "inverted", TRUE,
+ "centered", TRUE,
+ NULL);
+ g_object_bind_property (item, "label", button, "text", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "icon", button, "icon", G_BINDING_SYNC_CREATE);
+
+ g_object_set_data (G_OBJECT (button), "focus", focus);
+ g_object_set_data (G_OBJECT (focus), "focus", button);
+
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (focus, "clicked", G_CALLBACK (open_submenu), item);
+ g_signal_connect (button, "clicked", G_CALLBACK (close_submenu), item);
+
+ gtk_stack_add_named (GTK_STACK (gtk_widget_get_ancestor (GTK_WIDGET (toplevel), GTK_TYPE_STACK)),
+ GTK_WIDGET (box), gtk_menu_tracker_item_get_label (item));
+ gtk_widget_show (GTK_WIDGET (box));
+
+ box->tracker = gtk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SUBMENU, FALSE,
+ gtk_menu_section_box_insert_func,
+ gtk_menu_section_box_remove_func,
+ box);
+}
+
+GtkWidget *
+gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
+ GtkMenuSectionBox *toplevel)
+{
+ GtkMenuSectionBox *box;
+ GtkWidget *separator;
+ const gchar *label;
+
+ box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL);
+ box->size_group = g_object_ref (toplevel->size_group);
+ box->toplevel = toplevel;
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ label = gtk_menu_tracker_item_get_label (item);
+
+ if (label != NULL)
+ {
+ GtkWidget *title;
+
+ title = gtk_label_new (label);
+ g_object_bind_property (item, "label", title, "label", G_BINDING_SYNC_CREATE);
+ gtk_style_context_add_class (gtk_widget_get_style_context (title), GTK_STYLE_CLASS_SEPARATOR);
+ gtk_widget_set_halign (title, GTK_ALIGN_START);
+ box->separator = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ g_object_set (box->separator,
+ "margin-start", 12,
+ "margin-end", 12,
+ "margin-top", 6,
+ "margin-bottom", 3,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (box->separator), title);
+ gtk_container_add (GTK_CONTAINER (box->separator), separator);
+ gtk_widget_show_all (box->separator);
+ }
+ else
+ {
+ box->separator = separator;
+ g_object_set (box->separator,
+ "margin-start", 12,
+ "margin-end", 12,
+ "margin-top", 3,
+ "margin-bottom", 3,
+ NULL);
+ gtk_widget_show (box->separator);
+ }
+
+ box->tracker = gtk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SECTION, FALSE,
+ gtk_menu_section_box_insert_func,
+ gtk_menu_section_box_remove_func,
+ box);
+
+ return GTK_WIDGET (box);
+}
#include "gtkstack.h"
#include "gtksizegroup.h"
#include "a11y/gtkpopoveraccessible.h"
+#include "gtkmenusectionbox.h"
#define TAIL_GAP_WIDTH 24
#define TAIL_HEIGHT 12
GtkScrollable *parent_scrollable;
GtkAdjustment *vadj;
GtkAdjustment *hadj;
- GtkMenuTracker *tracker;
GdkRectangle pointing_to;
guint hierarchy_changed_id;
guint size_allocate_id;
GtkPopover *popover = GTK_POPOVER (object);
GtkPopoverPrivate *priv = popover->priv;
- g_clear_pointer (&priv->tracker, gtk_menu_tracker_free);
-
if (priv->window)
_gtk_window_remove_popover (priv->window, GTK_WIDGET (object));
return popover->priv->modal;
}
-static void
-gtk_popover_tracker_remove_func (gint position,
- gpointer user_data)
-{
- GtkWidget *box = user_data;
- GList *children;
- GtkWidget *child;
-
- g_assert (GTK_IS_BOX (box));
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
- child = g_list_nth_data (children, position);
- g_list_free (children);
-
- gtk_widget_destroy (child);
-}
-
-static void
-gtk_popover_item_activate (GtkWidget *button,
- gpointer user_data)
-{
- GtkMenuTrackerItem *item = user_data;
-
- gtk_menu_tracker_item_activated (item);
-
- if (gtk_menu_tracker_item_get_role (item) == GTK_MENU_TRACKER_ITEM_ROLE_NORMAL)
- gtk_widget_hide (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER));
-}
-
-static gboolean
-get_ancestors (GtkWidget *widget,
- GType widget_type,
- GtkWidget **ancestor,
- GtkWidget **below)
-{
- GtkWidget *a, *b;
-
- a = NULL;
- b = widget;
- while (b != NULL)
- {
- a = gtk_widget_get_parent (b);
- if (!a)
- return FALSE;
- if (g_type_is_a (G_OBJECT_TYPE (a), widget_type))
- break;
- b = a;
- }
-
- *below = b;
- *ancestor = a;
-
- return TRUE;
-}
-
-static void
-close_submenu (GtkWidget *button,
- gpointer data)
-{
- GtkMenuTrackerItem *item = data;
- GtkWidget *stack;
- GtkWidget *parent;
- GtkWidget *focus;
-
- if (gtk_menu_tracker_item_get_should_request_show (item))
- gtk_menu_tracker_item_request_submenu_shown (item, FALSE);
-
- focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
- get_ancestors (focus, GTK_TYPE_STACK, &stack, &parent);
- gtk_stack_set_visible_child (GTK_STACK (stack), parent);
- gtk_widget_grab_focus (focus);
-}
-
-static void
-open_submenu (GtkWidget *button,
- gpointer data)
-{
- GtkMenuTrackerItem *item = data;
- GtkWidget *stack;
- GtkWidget *child;
- GtkWidget *focus;
-
- if (gtk_menu_tracker_item_get_should_request_show (item))
- gtk_menu_tracker_item_request_submenu_shown (item, TRUE);
-
- focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
- get_ancestors (focus, GTK_TYPE_STACK, &stack, &child);
- gtk_stack_set_visible_child (GTK_STACK (stack), child);
- gtk_widget_grab_focus (focus);
-}
-
-static void
-gtk_popover_tracker_insert_func (GtkMenuTrackerItem *item,
- gint position,
- gpointer user_data)
-{
- GtkWidget *box = user_data;
- GtkWidget *stack;
- GtkWidget *widget;
- GtkSizeGroup *group;
-
- stack = gtk_widget_get_ancestor (box, GTK_TYPE_STACK);
- group = g_object_get_data (G_OBJECT (stack), "size-group");
-
- if (gtk_menu_tracker_item_get_is_separator (item))
- {
- GtkWidget *separator;
- const gchar *label;
-
- separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
-
- label = gtk_menu_tracker_item_get_label (item);
-
- if (label != NULL)
- {
- GtkWidget *title;
-
- title = gtk_label_new (label);
- g_object_bind_property (item, "label", title, "label", G_BINDING_SYNC_CREATE);
- gtk_style_context_add_class (gtk_widget_get_style_context (title), GTK_STYLE_CLASS_SEPARATOR);
- gtk_widget_set_halign (title, GTK_ALIGN_START);
- widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- g_object_set (widget,
- "margin-start", 12,
- "margin-end", 12,
- "margin-top", 6,
- "margin-bottom", 3,
- NULL);
- gtk_container_add (GTK_CONTAINER (widget), title);
- gtk_container_add (GTK_CONTAINER (widget), separator);
- gtk_widget_show_all (widget);
- }
- else
- {
- widget = separator;
- g_object_set (widget,
- "margin-start", 12,
- "margin-end", 12,
- "margin-top", 3,
- "margin-bottom", 3,
- NULL);
- gtk_widget_show (widget);
- }
- }
- else if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU))
- {
- GtkMenuTracker *tracker;
- GtkWidget *child;
- GtkWidget *button;
- GtkWidget *content;
-
- child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- g_object_set (child, "margin", 10, NULL);
-
- button = (GtkWidget *) g_object_new (GTK_TYPE_MODEL_BUTTON,
- "has-submenu", TRUE,
- "inverted", TRUE,
- "centered", TRUE,
- NULL);
- g_object_bind_property (item, "label", button, "text", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "icon", button, "icon", G_BINDING_SYNC_CREATE);
-
- gtk_container_add (GTK_CONTAINER (child), button);
- gtk_widget_show_all (child);
-
- g_signal_connect (button, "clicked", G_CALLBACK (close_submenu), item);
-
- gtk_stack_add_named (GTK_STACK (stack), child,
- gtk_menu_tracker_item_get_label (item));
- gtk_size_group_add_widget (group, child);
-
- widget = (GtkWidget *) g_object_new (GTK_TYPE_MODEL_BUTTON,
- "has-submenu", TRUE,
- NULL);
- g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "visible", widget, "visible", G_BINDING_SYNC_CREATE);
- gtk_widget_show (widget);
-
- g_signal_connect (widget, "clicked", G_CALLBACK (open_submenu), item);
-
- g_object_set_data (G_OBJECT (widget), "focus", button);
- g_object_set_data (G_OBJECT (button), "focus", widget);
-
- content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_widget_set_halign (content, GTK_ALIGN_FILL);
- gtk_widget_show (content);
- gtk_container_add (GTK_CONTAINER (child), content);
- tracker = gtk_menu_tracker_new_for_item_link (item, G_MENU_LINK_SUBMENU, TRUE,
- gtk_popover_tracker_insert_func,
- gtk_popover_tracker_remove_func, content);
-
- g_object_set_data_full (G_OBJECT (widget), "submenutracker", tracker, (GDestroyNotify)gtk_menu_tracker_free);
-
- gtk_widget_show (widget);
- }
- else
- {
- widget = gtk_model_button_new ();
- g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "visible", widget, "visible", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "role", widget, "action-role", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "toggled", widget, "toggled", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "accel", widget, "accel", G_BINDING_SYNC_CREATE);
-
- g_signal_connect (widget, "clicked", G_CALLBACK (gtk_popover_item_activate), item);
- }
-
- g_object_set_data_full (G_OBJECT (widget), "GtkMenuTrackerItem", g_object_ref (item), g_object_unref);
-
- gtk_container_add (GTK_CONTAINER (box), widget);
- gtk_box_reorder_child (GTK_BOX (box), widget, position);
-}
-
static void
back_to_main (GtkWidget *popover)
{
GMenuModel *model,
const gchar *action_namespace)
{
- GtkActionMuxer *muxer;
GtkWidget *child;
GtkWidget *stack;
- GtkWidget *box;
- GtkPopoverPrivate *priv;
- GtkSizeGroup *group;
g_return_if_fail (GTK_IS_POPOVER (popover));
g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model));
- priv = popover->priv;
-
- muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (popover));
-
- g_clear_pointer (&priv->tracker, gtk_menu_tracker_free);
-
child = gtk_bin_get_child (GTK_BIN (popover));
if (child)
- gtk_container_remove (GTK_CONTAINER (popover), child);
-
+ gtk_widget_destroy (child);
+
if (model)
{
stack = gtk_stack_new ();
- group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- g_object_set_data_full (G_OBJECT (stack), "size-group", group, g_object_unref);
gtk_stack_set_homogeneous (GTK_STACK (stack), FALSE);
gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
gtk_widget_show (stack);
gtk_container_add (GTK_CONTAINER (popover), stack);
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- g_object_set (box, "margin", 10, NULL);
- gtk_widget_show (box);
- gtk_stack_add_named (GTK_STACK (stack), box, "main");
- gtk_size_group_add_widget (group, box);
+ gtk_menu_section_box_new_toplevel (GTK_STACK (stack), model, action_namespace);
+ gtk_stack_set_visible_child_name (GTK_STACK (stack), "main");
g_signal_connect (popover, "unmap", G_CALLBACK (back_to_main), NULL);
g_signal_connect (popover, "map", G_CALLBACK (back_to_main), NULL);
-
- priv->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (muxer),
- model,
- TRUE,
- TRUE,
- action_namespace,
- gtk_popover_tracker_insert_func,
- gtk_popover_tracker_remove_func,
- box);
}
}